package sysprojectmg.utiles;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.sql.Date;
import java.text.DecimalFormat;
import java.text.ParseException;

/**
 * NtpClient - an NTP client for Java.  This program connects to an NTP server
 * and prints the response to the console.
 * 
 * The local clock offset calculation is implemented according to the SNTP
 * algorithm specified in RFC 2030.  
 * 
 * Note that on windows platforms, the curent time-of-day timestamp is limited
 * to an resolution of 10ms and adversely affects the accuracy of the results.
 * 
 * 
 * This code is copyright (c) Adam Buckley 2004
 *
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public License as published by the Free 
 * Software Foundation; either version 2 of the License, or (at your option) 
 * any later version.  A HTML version of the GNU General Public License can be
 * seen at http://www.gnu.org/licenses/gpl.html
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
 * more details.
 *  
 * @author Adam Buckley
 */
public class SntpClient {

    private NtpMessage msg = null;
    
    public SntpClient() throws IOException {
        String serverName = "nist1.aol-va.symmetricom.com";
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName(serverName);
        byte[] buf = new NtpMessage().toByteArray();
        DatagramPacket packet =
                new DatagramPacket(buf, buf.length, address, 123);
        socket.send(packet);
        packet = new DatagramPacket(buf, buf.length);
        socket.receive(packet);
        this.msg = new NtpMessage(packet.getData());
        System.out.println(msg.toString());
    }

    public static void main(String[] args) throws IOException, ParseException {
        String serverName = "nist1.aol-va.symmetricom.com";

        // Process command-line args
//        if (args.length == 1) {
//            serverName = args[0];
//        } else {
//            printUsage();
//            return;
//        }

//
        // Send request
        DatagramSocket socket = new DatagramSocket();
        InetAddress address = InetAddress.getByName(serverName);
        byte[] buf = new NtpMessage().toByteArray();
        DatagramPacket packet =
                new DatagramPacket(buf, buf.length, address, 123);

        // Set the transmit timestamp *just* before sending the packet
        // ToDo: Does this actually improve performance or not?
        NtpMessage.encodeTimestamp(packet.getData(), 40,
                (System.currentTimeMillis() / 1000.0) + 2208988800.0);

        socket.send(packet);


        // Get response
        System.out.println("NTP request sent, waiting for response...\n");
        packet = new DatagramPacket(buf, buf.length);
        socket.receive(packet);

        // Immediately record the incoming timestamp
        double destinationTimestamp =
                (System.currentTimeMillis() / 1000.0) + 2208988800.0;


        // Process response
        NtpMessage msg = new NtpMessage(packet.getData());

        // Corrected, according to RFC2030 errata
        double roundTripDelay = (destinationTimestamp - msg.originateTimestamp)
                - (msg.transmitTimestamp - msg.receiveTimestamp);

        double localClockOffset =
                ((msg.receiveTimestamp - msg.originateTimestamp)
                + (msg.transmitTimestamp - destinationTimestamp)) / 2;


        // Display response
        System.out.println("NTP server: " + serverName);
        System.out.println(msg.toString());

        System.out.println("Dest. timestamp:     "
                + NtpMessage.timestampToString(destinationTimestamp));

        System.out.println("Round-trip delay: "
                + new DecimalFormat("0.00").format(roundTripDelay * 1000) + " ms");

        System.out.println("Local clock offset: "
                + new DecimalFormat("0.00").format(localClockOffset * 1000) + " ms");
        System.out.println("Semana Actual: "
                + msg.obtenerSemana(msg.receiveTimestamp));
        
        socket.close();
    }

    /**
     * Prints usage
     */
    static void printUsage() {
        System.out.println(
                "NtpClient - an NTP client for Java.\n"
                + "\n"
                + "This program connects to an NTP server and prints the response to the console.\n"
                + "\n"
                + "\n"
                + "Usage: java NtpClient server\n"
                + "\n"
                + "\n"
                + "This program is copyright (c) Adam Buckley 2004 and distributed under the terms\n"
                + "of the GNU General Public License.  This program is distributed in the hope\n"
                + "that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\n"
                + "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
                + "General Public License available at http://www.gnu.org/licenses/gpl.html for\n"
                + "more details.");
    }
    
    public int obtenerSemanaActual() throws ParseException{
        int res = 0;
        res = this.msg.obtenerSemana(msg.receiveTimestamp);
        return res;
    }
    
    public int obtenerSemanaByFecha(String cadenaFecha) throws ParseException{
        int res = 0;
        //cadena fecha "2011-06-04"
        Date fecha2 = Date.valueOf(cadenaFecha);
        long ms = fecha2.getTime();
        Double timestamp = ms/1000.0;
        timestamp = timestamp + (2208988800.0);
        res = this.msg.obtenerSemana(timestamp);
        return res;
    }

    public int obtenerAnioActual() throws ParseException {
        int res = 0;
        res = this.msg.obtenerAnio(msg.receiveTimestamp);
        return res;
    }
}
